home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
storage.zip
/
STORAGE.DOC
< prev
next >
Wrap
Text File
|
1991-02-09
|
11KB
|
215 lines
STORAGE.PAS
By
Marcos R. Della
This Unit was designed to allow you the user to save and restore
several bodies of text or information into a single file and restore
that information based on a single LONGINT. Examples of usage are:
In a BBS system where you are creating a message base and need to
save several messages however do not want to create several files.
You also want the messages compressed to save disk space
In a program where you are storing variable length records that you
want to keep track of in an indexed database. Your index key can
use the LONGINT returned by the storage system as your reference
into the record. The record will be stored in compressed format.
I'm sure that people can think of all kinds of neat things to do with
this system. The main advantage that you have with this object is
that ANY kind of data can be stored {Length: 0 < sizeof(data) < 65530}
as long as it fits in the buffer space.
BRIEF DESCRIPTION:
------------------
The way it is supposed to work is that you either create or open a
previously created file. You can define how big you want your
read/write buffer for the file and how you want to open it (read,
write, or read/write). Once open, your basic functions consist of
"writing" messages or "reading" messages.
To write a message, you create your own buffer of any size from 1 to
65530 bytes in length. Note that the system will write out everything
in that block that you assign including wasted space, pointers,
whatever. If you would like to store a series of strings, you could
possibly do the following:
TYPE str_buffer = ARRAY[1..128] OF STRING;
VAR mybuff : str_buffer;
This would create a block of memory that is 128 * 256 bytes long. The
only problem here is that all wasted memory will also be stored if you
select it that way. Doing a little pre-buffering is a prefered method.
To write your information, you simply call the write routine with the
location of your buffer and how many bytes to write out. The system
will return a LONGINT that is your KEY to retrieving the information
at a later date.
keyvalue := TStorage.WriteMsg(SIZEOF(mybuff),mybuff);
To later read the information back, the storage system will grab a
block of memory equal to the original size, and return to you a
pointer to that block...
bytesread := TStorage.ReadMsg(keyvalue,mybufptr);
mybuff := str_buffer(mybufptr^);
The information is automatically stored in compressed format on the
disk so you don't have to worry about all that. Thats about all there
is to the whole thing! There are other routines included to do
various other things, but you now have the basics!
OBJECT DESCRIBED:
-----------------
Note that the information both stored and retrived are limited to 65530
characters in length. In the current version, this will require you to
have somewhere on your heap that much space. In the future this routine
will be made EMS aware so that it will grab the best option for heap
storage and manipulation out there...
The OBJECT TStorage is a Child of the BufStream Object. This means that
it still retains all the lower level stuff from BufStream, DOSStream, and
TStream if you have some sort of use for that.
The routines provided are as follows:
TStorage.Init(FNameStr, Mode, BufSize)
This routine will initialize the file that you are going to be reading
from or writing to. You can use the stCreate, stOpenWrite, stOpenRead,
or stOpen as your mode. If you use the stCreate, the system will write
over your previous file. If you use stOpenWrite, you can ONLY write
to the file, you cannot do reads and visa-versa with stOpenRead. If
you use stOpen, then you can do both operations at the same time.
This is another item that in the future will be changed to do record
locking of the specified section you are writing to so that other
users on a network can read from the various other parts of the file.
The BufSize defines the internal buffer size that the system will use
to buffer your I/O reads. Borland recommends around 1024 for standard
usage. You might make it bigger or smaller depending on your needs.
TStorage.WriteMsg(NumBytes : WORD; Buf) : LONGINT
This takes a buffer that you define and will write out NumBytes of
continuous memory out to the disk. While writing the information
out, it is running it through the inherited compression routine.
This will then return a LONGINT to the user as the reference point
for the information stored.
TStorage.ReadMsg(INdex : LONGINT; VAR Buf : POINTER) : WORD
This is how you retrieve your text. You pass the index that you got
earlier from TStorage.WriteMsg to this routine and it will pass you a
buffer pointer. This points to the exact same stuff that was earlier
stored. You can then overlay your TYPE onto the pointer to retrieve
specific information that you want. NOTE: If the index that you pass
is not the beginning of a stored pattern, the ReadBuf routine will
assume that you are reading a STANDARD text file and will rewind
and read the ENTIRE file into the buffer. This is how you can use
the same routine to read normal text files as well as those created
by this Object. If the message was deleted by the DeleteMsg routine,
you will get an errorlevel of 100 (Disk Read Error) returned to you
from the function.
TStorage.DeleteMsg(Index)
This function does not actually delete the message out of the stream
as this would then mess up all subsequent index pointers. Instead, it
changes the compression routine variable to $FF indicating that the
message is no longer valid. To actually take the messages out of the
stream, you need to use the CleanUpMsg procedure.
TStorage.CleanUpMsg
This procedure will scan the message stream, and re-write it out to a
seperate file leaving out all the deleted messages. It then creates
a linked list of the old indexes and their new values. This is then
used by you, the user, to change all your old saved index values.
NOTE: Make sure that you do the index change BEFORE calling the
TStorage.Done routine as this will remove your list from memory and
all your pointers will be subsiquently screwed up. If there is a
problem and you need to restore the previous file, you can rename
.$$$ file back to your filename. The .$$$ file is not deleted until
the TStorage.Done is called.
TStorage.NewIndex(Index) : LONGINT
When you call this routine with an old index number, it will return
to you the new index reference number. You'll get a -1 if the system
cannot fine an original index number. To use this, you can scan
through your recorded indexes in your data file sequentially and call
this routine with each one you get. Then replace the old value with
the new value. If you get a -1 as your return, then the old message
was either originally deleted or lost to the system. This will ALWAYS
return a -1 if you haven't made a VALID call to TStorage.CleanUpMsg.
It will also reset after a TStorage.Done has been executed. Make sure
that you use this after the TStorage.CleanUpMsg routine if you want
to retain the changes made.
TStorage.DeleteCleanUp
If you decide that for some reason something went wrong somewhere and
everything is screwed up, you can prevent TStorage.Done from replacing
your original msg file by calling this routine. It will remove the
.$$$ file from the disk and clear out all TStorage.NewIndex references.
TStorage.Compress(NumBytes : WORD; CompType : BYTE; VAR Buf) : WORD
This current compression routine uses the Splay tree system. If you
want more information, see the bottom of this documentation. This
will take "NumBytes" of information located in the "Buf" and then
compress them and store them to the TBufStream at the Current seeked
location. Make sure that your pointer is at the correct place before
you call this routine. It then returns exactly how many characters
were written out to the disk.
TStorage.DeCompress(NumBytes : WORD; CompType : Byte; VAR Buf)
Same as the compression except that this goes backwards. The NumBytes
defines how big the original text should have been. This is generally
retrieved from the header information.
TStorage.InitCompress;
This is the routine that the compression routines will call prior to
actually compressing or decompressing the information. This is so that
you can initialize any local variables or whatever you feel like for
the compression routines.
TStorage.Done
Here is where you clean up all the messes, close all the files, and
return all the used heap back. Remember to call this when your done
using the routines
ERRORS Returned
When you check the TStorage.Status Integer, if you do not get an stOk
returned, then something went wrong. To identify it from this Unit,
You can check TStorage.Status against stStoreError. Errors also
included are stStoreReadErr, stStoreWriteErr, and stStoreUnknownErr.
These are stored in the TStorage.ErrorInfo location.
---------------------------------------------------------------------------
These routines were originally designed as a message storage routine for a
new BBS system message base that we are putting together, however we have
used this storage format for a varity of purposes as you can store variable
length messages to one file and only have to keep track of an index. It
also attempts to save on disk space which is ALWAYS at a premium around
here.
If you have any suggestions or improvments on this file or its usage, or
would just like to chat, you can reach me at the following:
Marcos R. Della
5084 Rincon Ave.
Santa Rosa, CA 95409
CIS: 71675,765
---------------------------------------------------------------------------}